package com.tuzhi.filter;

import com.alibaba.fastjson2.JSON;
import com.tuzhi.base.web.helper.AjaxResultHelper;
import com.tuzhi.base.web.util.ServletUtil;
import com.tuzhi.common.constants.ResultConstant;
import com.tuzhi.common.domain.LoginUserBO;
import com.tuzhi.config.ConstantConfig;
import com.tuzhi.security.service.SecurityConfig;
import com.tuzhi.security.service.UserService;
import com.tuzhi.security.service.impl.TokenServiceImpl;
import com.tuzhi.sys.scurity.AuthService;
import com.tuzhi.util.StringTzUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

import static com.tuzhi.common.constants.security.Constants.USER_INFO;

@WebFilter(filterName = "TuZhiSecurityFilter", urlPatterns = "/*")
public class TuZhiSecurityFilter implements Filter {

    @Value("${server.servlet.context-path:/}")
    private String contextPath;

    private static final Logger log = LoggerFactory.getLogger(TuZhiSecurityFilter.class);

    @Autowired
    SecurityConfig securityConfig;

    @Autowired
    UserService userService;

    @Autowired
    TokenServiceImpl tokenService;
    @Autowired
    AuthService authService;
    @Autowired


    final static String packageName = "com.tuzhi.security.service.impl";
    final static String configClassName = "SecurityConfigImpl";
    final static String userServiceClassName = "UserServiceImpl";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.debug("启动了ZhfSecurityFilter过滤器功能");

        if (packageName.equals(securityConfig.getClass().getPackage().getName())
                && configClassName.equals(securityConfig.getClass().getSimpleName())) {
            log.info("TuZhiSecurityFilter 使用默认配置{}，需要自定义配置，请重新实现SecurityConfig，或者继承SecurityConfigImpl",
                    configClassName);
            log.info("\n@Primary\n" +
                    "@Service\n" +
                    "public class MySecurityConfig extends SecurityConfigImpl {\n" +
                    "}");
        }
        if (packageName.equals(userService.getClass().getPackage().getName())
                && userServiceClassName.equals(userService.getClass().getSimpleName())) {
            log.info("ZhfSecurity使用默认用户服务{}，需要自定义配置，请重新实现UserService，或者继承UserServiceImpl",
                    userServiceClassName);
            log.info("\n@Primary\n" +
                    "@Service\n" +
                    "public class UserService2Impl extends UserServiceImpl {\n" +
                    "}");
        }
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = httpServletRequest.getRequestURI();
        String authUrl = httpServletRequest.getHeader("authUrl");
        //String Authorization = httpServletRequest.getHeader("Authorization");
        // log.info("authUrl-{}，Authorization-{}", authUrl, Authorization);
        //现在用网关做权限校验， 直接用网关设置的地址来校验，不取直接的请求，
        //如果是 authUrl 没有地址，表示是己校验过的。
        if (StringUtils.isEmpty(authUrl)) {
            //log.info("没有需要校验权限的请求");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
            //uri = clearContextPath(uri);
        }
        uri = authUrl;
        if (securityConfig.isPermitUri(uri)) {
            //log.debug("不拦截地址{}", uri);
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //需要登录
        if (!securityConfig.isIntercept(uri)) {
            String token = tokenService.getToken(httpServletRequest);//获取token
            if (StringTzUtil.isBlankNull(token)) {
                log.debug("token为空!");
                ServletUtil.renderJson(response, AjaxResultHelper.buildJson(ResultConstant.ERR_TOKEN_NULL));
                return;
            }

            LoginUserBO loginUserBO = tokenService.getLoginUser(httpServletRequest);//根据token获取用户信息
            log.info("根据token获取用户信息："+JSON.toJSONString(loginUserBO));
            Collection<String> roleNames = authService.findUserRoleName4CacheAndDb(loginUserBO.getUserId());
            if (CollectionUtils.isNotEmpty(roleNames)) {
                if (roleNames.contains(ConstantConfig.SUPER_ROLE_NAME)) {
                    loginUserBO.setSupper(true);
                }
                if (roleNames.contains(ConstantConfig.ENTERPRISE_MANAGER_ROLE_NAME)) {
                    loginUserBO.setDeptMgr(true);
                }
                loginUserBO.setRoles(roleNames);
            }
            boolean valid = tokenService.verifyLoginUserBO(loginUserBO);//是否合法用户请求（是否过期判断）
            if (!valid) {
                log.debug("无效token={}", token);
                ServletUtil.renderJson(response, AjaxResultHelper.buildJson(ResultConstant.ERR_TOKEN_ERR));
                return;
            }
           /*
           //刷新token操作，放到网关了
           String refreshToken = tokenService.tokenIsExpRefresh(token);//刷新用户token
            response.addHeader("refreshToken", refreshToken);
            */
            /**
             * 在权限过滤器的 response 增加 用户信息，tuzhi-auth-sys 安装了这个依赖，网关调用 /auth/permission/check的鉴权接口会返回用户信息，然后网关会把这个用户信息增加到HttpRequest的Header
             */
            response.addHeader(USER_INFO, JSON.toJSONString(loginUserBO));
            //如果是超级用户，则给他通过，不校验
            // 权限校验
            /*if (!authService.superAdmin(loginUserBO.getUserId()) && !authService.enterpriseAdmin(loginUserBO.getUserId())) {
                //判断是否有权限
                if (!authService.hasUri4User(loginUserBO.getUserId(), uri)) {
                    log.debug("{}没有该地址权限{}", loginUserBO.getUserName(), uri);
                    ServletUtil.renderJson(response,
                            AjaxResultHelper.buildJson(ResultConstant.ERR_NOT_PERMISSION));
                    return;
                }
                log.debug("{}权限校验通过{}", loginUserBO.getUserName(), uri);
            }*/

        }

        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        log.debug("{} destroy...", this.getClass());
    }
}
